from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker

from app.config import Settings


async def get_session_factory(config: Settings) -> sessionmaker:
    engine = create_async_engine(
        make_connection_string(config),
        future=True,
        connect_args={"connect_timeout": 120},
    )

    return sessionmaker(
        bind=engine,
        expire_on_commit=False,
        class_=AsyncSession,
        future=True,
        autoflush=False,
    )


def make_connection_string(config: Settings, async_fallback: bool = False) -> str:
    conn_str = (
        f"mysql+aiomysql://{config.db.user}:{config.db.password}@{config.db.host}:"
        f"{config.db.port}/{config.db.name}"
    )
    if async_fallback:
        conn_str += "?async_fallback=True"
    return conn_str
